#include <stdio.h>
#include <stdlib.h>
#include <mp4v2/mp4v2.h>

int get_video_thumbnail(const char *input_filename, const char *output_filename, int time_in_seconds) {
    MP4FileHandle mp4File = MP4Read(input_filename);
    if (mp4File == MP4_INVALID_FILE_HANDLE) {
        fprintf(stderr, "无法打开MP4文件: %s\n", input_filename);
        return 1;
    }

    MP4TrackId videoTrackId = MP4FindTrackId(mp4File, 0, MP4_VIDEO_TRACK_TYPE, 0);
    if (videoTrackId == MP4_INVALID_TRACK_ID) {
        fprintf(stderr, "未找到视频轨道\n");
        MP4Close(mp4File);
        return 1;
    }

    // 获取轨道时间尺度
    uint32_t timeScale = MP4GetTrackTimeScale(mp4File, videoTrackId);
    MP4Duration sampleTime = time_in_seconds * timeScale; // 转换为轨道时间单位
    
    MP4SampleId sampleId = MP4GetSampleIdFromTime(mp4File, videoTrackId, sampleTime);
    if (sampleId == MP4_INVALID_SAMPLE_ID) {
        fprintf(stderr, "在时间点 %d 秒处无法找到有效采样\n", time_in_seconds);
        MP4Close(mp4File);
        return 1;
    }

    uint8_t *buffer;
    uint32_t bufferSize;
    MP4ReadSample(mp4File, videoTrackId, sampleId, &buffer, &bufferSize);

    FILE *file = fopen(output_filename, "wb");
    if (file == NULL) {
        fprintf(stderr, "无法创建输出文件: %s\n", output_filename);
        MP4Close(mp4File);
        free(buffer); // 释放MP4ReadSample分配的内存
        return 1;
    }
    
    fwrite(buffer, 1, bufferSize, file);
    fclose(file);
    
    // 释放MP4ReadSample分配的内存
    free(buffer);

    MP4Close(mp4File);
    printf("成功从 %s 第 %d 秒提取缩略图到 %s\n", input_filename, time_in_seconds, output_filename);
    return 0;
}

int main(int argc, char *argv[]) {
    // 检查命令行参数
    if (argc != 4) {
        printf("用法: %s <输入MP4文件> <输出文件> <时间点(秒)>.\n", argv[0]);
        printf("示例: %s video.mp4 thumbnail.264 5\n", argv[0]);
        return 1;
    }
    
    const char *input_file = argv[1];
    const char *output_file = argv[2];
    int time_seconds = atoi(argv[3]);
    
    // 验证时间参数
    if (time_seconds < 0) {
        fprintf(stderr, "错误: 时间点必须是非负数\n");
        return 1;
    }
    
    // 调用函数提取缩略图
    return get_video_thumbnail(input_file, output_file, time_seconds);
}